package com.idiot.web.base;

import com.google.code.kaptcha.Constants;
import com.google.code.kaptcha.impl.DefaultKaptcha;
import com.idiot.domain.common.exceptions.model.ResponseInfo;
import com.idiot.domain.common.utils.EncodeMD5;
import com.idiot.domain.model.Log;
import com.idiot.domain.model.Menu;
import com.idiot.domain.model.User;
import com.idiot.domain.model.enums.LogTypeEnums;
import com.idiot.service.ILogService;
import com.idiot.service.IMenuService;
import com.idiot.service.IUserService;
import org.apache.commons.lang.StringUtils;
import org.apache.shiro.SecurityUtils;
import org.apache.shiro.authc.AuthenticationException;
import org.apache.shiro.authc.UsernamePasswordToken;
import org.apache.shiro.subject.Subject;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.stereotype.Controller;
import org.springframework.ui.Model;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RequestMethod;
import org.springframework.web.servlet.ModelAndView;
import com.idiot.domain.common.utils.Constants.Regular;
import javax.annotation.Resource;
import javax.imageio.ImageIO;
import javax.servlet.ServletOutputStream;
import java.awt.image.BufferedImage;
import java.util.List;

/**
 * Created by idiot on 2016/12/13.
 */
@Controller
public class IndexController extends SuperController{

    private static final Logger logger = LoggerFactory.getLogger(IndexController.class);

    @Resource
    private IUserService userService;
    @Resource
    private ILogService logService;
    @Resource
    private IMenuService menuService;
    @Resource
    private DefaultKaptcha captchaProducer;

    @RequestMapping(value = {"/"},method = RequestMethod.GET)
    public String root(){
        return "redirect:login.html";
    }

    @RequestMapping(value = {"login"},method = RequestMethod.GET)
    public String toLogin(){
        return "login";
    }

    @RequestMapping(value = "loginIn")
    public String login(User info, String captcha, Model model){
        ResponseInfo<String> responseInfo = new ResponseInfo<>();
        logger.info("开始==》【登录】");
        logger.info("开始判断数据是否为空...");
        //用户信息非空判断  为空返回登录页面
        if(null == info || StringUtils.isEmpty(info.getUserName()) || StringUtils.isEmpty(info.getUserPassword()) || StringUtils.isEmpty(captcha)){
            model.addAttribute("error","用户名、密码、验证码不能为空...");
            return "login";
        }
        logger.info("开始判断验证码是否正确...");
        //判断验证码  错误返回登录页面
        //从session中取出验证码text值
        String expected = (String) request.getSession().getAttribute(com.google.code.kaptcha.Constants.KAPTCHA_SESSION_KEY);
        if(!captcha.equalsIgnoreCase(expected)){
            logger.error("验证码错误...");
            model.addAttribute("error","验证码有误...");
            return "login";
        }
        logger.info("开始shiro权限验证...");
        //shiro验证
        try {
            Subject currentUser = SecurityUtils.getSubject();
            UsernamePasswordToken token = new UsernamePasswordToken(info.getUserName(), EncodeMD5.GetMD5Code(info.getUserPassword()));
            currentUser.login(token);
            if(currentUser.isAuthenticated()){
                //权限验证通过   把当前用户添加到session 并且返回首页
                session.setAttribute(Regular.onlineUser, userService.getUserByName(info.getUserName()));
                //写入数据库登录日志
                Log log = new Log();
                log.setLogTypeId(LogTypeEnums.LOGIN.getValue());        //设置日志类型
                log.setRequestUrl(request.getRequestURI().toString());  //设置请求路径
                log.setUserId(getUser().getUserId());                        //设置userId
                logService.addloginLog(log);
                logger.info("登录验证成功...进入首页...");
                return "redirect:index.html";
            }
        } catch (AuthenticationException e) {
            logger.error("登录验证失败...错误原因："+e.getMessage());
            e.printStackTrace();
        }
        model.addAttribute("error", "密码错误或者用户名不存在,请重试...");
        logger.info("返回登录页面...");
        return "login";
    }

    /**
     * @author idiot
     * @description 跳转首页
     * @return
     */
    @RequestMapping(value = {"index.html"})
    public String indexPage(Model model){
        logger.info("加载首页资源...");
        //获取用户信息  从session里面
        User user = getUser();
        if(user == null){
            logger.info("用户信息有误...");
            request.setAttribute("error", "该用户不存在,请重试...");
            return "redirect:login.html";
        }
        //从数据库中查询menu  一级菜单
        List<Menu> menus = menuService.getFirstLevelMenusByUserId(user.getUserId());
        //加载二级菜单信息
        for(Menu menu : menus){
            List<Menu> menuItems = menuService.getMenusByParenrId(menu.getMenuId());
            menu.setListMenus(menuItems);
        }
        model.addAttribute("menus", menus);
        model.addAttribute(Regular.onlineUser,getUser());
        return "index";
    }

    /**
     * @dscription 欢迎页面
     * @return
     */
    @RequestMapping(value = "welcome", method = RequestMethod.GET)
    public String welcome(){
        return "welcome";
    }

    /**
     * @description 退出时加载登录页
     * @return
     */
    @RequestMapping(value = "loginOut", method = RequestMethod.GET)
    public String loginOut(){
        session.setAttribute(Regular.onlineUser, null);
        return "redirect:login.html";
    }

    /**
     * @author idiot
     * @description  生成验证码
     * @throws Exception
     */
    @RequestMapping(value = "captcha-image")
    public ModelAndView getKaptchaImage() throws Exception {
        response.setDateHeader("Expires", 0);
        response.setHeader("Cache-Control", "no-store, no-cache, must-revalidate");
        response.addHeader("Cache-Control", "post-check=0, pre-check=0");
        response.setHeader("Pragma", "no-cache");
        response.setContentType("image/jpeg");
        String capText = captchaProducer.createText();
        session.setAttribute(Constants.KAPTCHA_SESSION_KEY,capText);//验证码存放到session中
        BufferedImage bi = captchaProducer.createImage(capText);
        ServletOutputStream out = response.getOutputStream();
        ImageIO.write(bi, "jpg", out);
        try {
            out.flush();
        } finally {
            out.close();
        }
        return null;
    }
}
